package futbol.tacticas.concursantes.TacticaCaccy;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Vector;

import futbol.Futbol;
import futbol.General;
import futbol.tacticas.Comando;
import futbol.tacticas.ComandoGolpearBola;
import futbol.tacticas.ComandoIrA;
import futbol.tacticas.ComandoPase;
import futbol.tacticas.ComandoTiroAPuerta;
import futbol.tacticas.SituacionJugadores;

public class Goalkeeper extends Skills
{
	Manager tecnico;
	private static Logger log = Logger.getLogger(Goalkeeper.class);
	
	public static final double  radioMaximo = 55;
	public static final double  radioDeActividad = 30;
	
	public Goalkeeper(int numJugador, int xInicial, int yInicial,int fuerza, Manager tec, Defense escuadra) {
		super(numJugador, xInicial, yInicial, fuerza, tec,escuadra);
		tecnico = tec;
	}

	@Override
	public Vector<Comando> getComandos() 
	{
		Vector<Comando> comandos=new Vector();
		Ball miPelota = tecnico.getMiPelota();
		Point2D moviment = new Point2D.Double(this.x,this.y); //Movimiento por defecto quedarme quieto
		ArrayList<Ball> trayectoria = tecnico.getTrayectoria();
		Play[] interceptores = tecnico.getMejoresInterceptores();
		
		
		
		if(tecnico.getBolaPrevista(1000).isPelotaConPeligroDeGol()==1){
			moviment = tecnico.getPelotaAInterceptarTemporal(trayectoria,this.getPointAcutal(),this.velocidad,7);
			comandos.add(new ComandoIrA(numero,moviment.getX(),moviment.getY()));
		
			
		}else if(interceptores[0].indiceJugador==numero&&tecnico.tenemosPelota()>0){
			int indexPilota = interceptores[0].indicePelota; 
			
		
			for(; indexPilota<trayectoria.size()   &&  trayectoria.get(indexPilota).distance(-160,0)>radioMaximo	; indexPilota++);
			
			if(indexPilota==trayectoria.size())
				indexPilota--;
			
			
			if(trayectoria.get(indexPilota).distance(-160,0)<radioMaximo	){
				moviment = trayectoria.get(indexPilota);
				comandos.add(new ComandoIrA(numero,moviment.getX(),moviment.getY()));
			}else{
				moviment = posicionDeCubrir(miPelota);
				comandos.add(new ComandoIrA(numero,moviment.getX(),moviment.getY()));
			}
			
		}else if(interceptores[0].indiceJugador==numero&&tecnico.tenemosPelota()>5){
			moviment = trayectoria.get(interceptores[0].indicePelota);
			comandos.add(new ComandoIrA(numero,moviment.getX(),moviment.getY()));
		}
		else{
			
			//cubrir la trayectoria directa
			moviment = posicionDeCubrir(miPelota);
			comandos.add(new ComandoIrA(numero,moviment.getX(),moviment.getY()));
		}
		moviment = null;
		Point2D pase = null;
		if(miPelota.velocidad<=15&&miPelota.distance(this)<=11){
			
				pase = paseComodeADefensa();
				
				
				if(pase==null){
					
					moviment = getSiguentePuntoDeRegateo();
					
					
					
					if(moviment!=null){
						//log.debug("Benji regatea");
						
						if(!emPrenenLaPilota(this, moviment)){
							comandos.add(new ComandoIrA(numero,moviment.getX(), moviment.getY()));
							pase = toqueDeBalonControlado(moviment, miPelota);
						}else{
							//Aixo fa que es faci un despeje
							moviment=null;
						}
					}
					
				}
				
				if((moviment==null&&pase==null)||this.distance(-160,0)> this.radioMaximo){
					//log.debug("Benji despeja");
					pase = tecnico.despejarPelotaParaPortero(this.numero, Math.toRadians(-90), Math.toRadians(90));
					double [] pun = FutbolTools.toquePreciso(this, tecnico.getMiPelota(), pase.getX(), pase.getY());
					pase = new Point2D.Double( pun[0], pun[1]);
					
				}
				
			
				
				comandos.add(new ComandoGolpearBola(numero,pase.getX(), pase.getY()));
				
			}
		
       
	    return comandos;
	}
	
	public Point2D toqueDeBalonControlado(Point2D moviment, Point2D miPelota){
		Point2D pase = null;
		
		
		pase = tecnico.getPosicionDeToque(moviment.getX(), moviment.getY(), miPelota, 2);
		double [] pun = FutbolTools.toquePreciso(this, tecnico.getMiPelota(), pase.getX(), pase.getY());
		return new Point2D.Double( pun[0], pun[1]);
	}
	
	public Point2D getSiguentePuntoDeRegateo(){
		Point2D jugadorObjectiu= null;
		Point2D moviment= null;
		double anguloDeseado = FutbolTools.aA(FutbolTools.calcAngulo(this, 0,0),0);
		int indexJugadorAlQueDirijirme = getJugadorAlQueDirigirme(anguloDeseado);
		
		
		if(indexJugadorAlQueDirijirme!=this.numero){
			jugadorObjectiu = sj.getMisJugadores()[indexJugadorAlQueDirijirme];
			double [][] angles = tecnico.getRutasLibres(this, 30,jugadorObjectiu);
			double[] punto = tecnico.irHaciaConEvasion(this, angles, jugadorObjectiu);
			if(punto!=null){
				moviment = new Point2D.Double(punto[0], punto[1]);
			}
		}
	
		return moviment;
	}
	
	public Point2D paseComodeADefensa(){
		
		int indexJugadorAlQuePasar = this.numero;
		indexJugadorAlQuePasar = tecnico.paseSegur(this, 10);
		
		if(indexJugadorAlQuePasar==this.numero){
			return null;
		}
		
		double [] p = FutbolTools.pasePreciso(this, tecnico.getMiPelota(), indexJugadorAlQuePasar);
		Point2D pase = null;
		if(p!=null){
			pase = new Point2D.Double(p[0], p[1]);
		}
	
		
		return pase;
	}
	
	/*
	public int getJugadorAlQuePasar(){
		Point[] companys = sj.getMisJugadores();
		double errorMinimo = 999;
		int indexJugadorAlQuePasar = -1;
		int indexJugadorAux = -1;
		Point jugadorAlQuePasar= null;
		
		for(int i =0; i<companys.length; i++){
			indexJugadorAux = tecnico.paseSegur(this, 10);
			if(indexJugadorAux!=this.numero){
				indexJugadorAlQuePasar = indexJugadorAux;
			}
		}
	}
	*/
	
	public int getJugadorAlQueDirigirme(double anguloD){
		
		Point[] companys = sj.getMisJugadores();
		double anguloDeseado = FutbolTools.aA(anguloD,0);
		double anguloConJugador = 0;
		double errorMinimo = 999;
		double error = 999;
		int indexJugadorAlQueCorrer = this.numero;
		Point jugadorAlQueCorrer= null;
		
		for(int i=0; i < companys.length ; i++){
			if(i!=this.numero){
				jugadorAlQueCorrer = companys[i];
				if(jugadorAlQueCorrer.distance(this)<FutbolTools.distanciaMaximaDePelota(this.fuerza)+30){
					anguloConJugador = FutbolTools.aA(FutbolTools.calcAngulo(this, jugadorAlQueCorrer),0);
					
					error = Math.abs(anguloConJugador-anguloDeseado);
					
					if(error<errorMinimo){
						errorMinimo = error;
						indexJugadorAlQueCorrer = i;
					}
				}
			}
		}
		
		return indexJugadorAlQueCorrer;
	}
	
	private int getXRespectandoDistancia(double Y)
	{
		
		if(Y>radioDeActividad)
			Y = radioDeActividad;
		return (int) Math.round( -160 + (radioDeActividad)*Math.cos( Math.asin(Y/(radioDeActividad)) ) );
		
		
		}
	
	private Point2D posicionDeCubrir(Ball miPelota){
		double anguloConPelota = FutbolTools.calcAngulo(this,miPelota);
		double x = -160 + this.radioDeActividad*Math.cos(anguloConPelota);
		double y = 0 + this.radioDeActividad*Math.sin(anguloConPelota);
		
		return new Point2D.Double(x,y);
	}
	
	
	
	
	
	
	public String getName(){
		return "EdWarner";
	}
	
	private boolean emPrenenLaPilota(Skills jugador, Point2D puntoDeseado)
	{
		double[] posicion = new double[2];
		
		posicion = 	tecnico.irHaciaConEvasion(	jugador,
				tecnico.getRutasLibres(jugador, 30, puntoDeseado),
				puntoDeseado);
		
		if(posicion==null)
		{
			//log.debug("posicion == null");
			return true;
		}
		
		Point2D.Double toque = tecnico.getPosicionDeToque(posicion[0], posicion[1], tecnico.getMiPelota(), 2);
		
		double[] toquePos = FutbolTools.toquePreciso(jugador, tecnico.getMiPelota().getCopia(), toque.x, toque.y);
		
		Ball pelotaHipo = FutbolTools.createPelotaSegunDestino(jugador, jugador.fuerza, tecnico.getMiPelota(), toquePos[0], toquePos[1]);
		
		ArrayList<Ball> tray = new ArrayList<Ball>();
		
		FutbolTools.calculTrajectoria(pelotaHipo, tray);
		
		
		Play h = tecnico.getMejoresInterceptoresContrariosHipotetico(tray, null)[0];
		
		return ( h.indicePelota == 0 );
	}
	
}
